# -*- coding: utf-8 -*-
import json
import socket
import threading

from temp.log_util import logger
from temp.readyaml import yaml_r
from temp.student_db import student_db

# 路由表
router_table = {}


# 装饰器维护路由表
def router(path):
    def wrapper(func):
        def inner(self, *args, **kwargs):
            logger.info("Run..")
            return func(self, *args, **kwargs)

        router_table[path] = inner
        return inner

    return wrapper


class stuweb:
    def __init__(self):
        self.recv_data = None
        self.db = student_db()
        self.__data = None

    def startServer(self):
        my_yaml = yaml_r()
        # 创建socket对象
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # ??????
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 设置服务器启动ip端口
        host = my_yaml.readyaml()['host_config']["host"]
        port = my_yaml.readyaml()['host_config']["port"]
        server.bind((host, port))
        logger.info(f"服务器启动 String on {host}:{str(port)}")
        server.listen(256)
        while True:
            client, ip_port = server.accept()
            logger.info(f"客户端地址{ip_port[0]} {ip_port[1]}")
            # 创建一个子线程去处理客户端的请求，主线程再去接受其它客户端的请求
            t = threading.Thread(target=self.handleClientRequest, args=(client,))
            # 设置守护线程
            t.daemon = True
            # 启动子线程去处理客户端请求
            t.start()

    # 获取相应报文
    def handleClientRequest(self, client):
        # 读取客户端的请求内容
        self.recv_data = client.recv(4096).decode("utf-8")
        # 判断与客户端的连接是否断开
        if len(self.recv_data) == 0:
            client.close()
            return
        # 解析客户端请求数据
        request = self.parseRequest(self.recv_data)
        response = self.__route(request)
        logger.info(response.decode("utf-8"))
        client.send(response)
        client.close()

    # 拆分请求报文
    def parseRequest(self, recv_data):

        request = {
            "method": "",
            "path": "",
            "values": {}
        }

        recv_data = recv_data.split()

        request["method"] = recv_data[0]
        path = recv_data[1]
        if "?" in path:
            tmp = path.split("?")
            path = tmp[0]
            params = tmp[1].split("&")
            for s in params:
                k, v = s.split("=")
                request["values"][k] = v

        request["path"] = path
        # 返回解析结果
        logger.info(request)
        return request

    def __route(self, request):
        path = request.get("path")
        logger.info(path)
        # 匹配路由 路径和接口函数
        interface = router_table.get(path)
        response_body = interface(self, request)
        response = "HTTP/1.1 200 OK\r\n"
        response += "Content-Type: application/json;charset=utf-8\r\n"
        response += "Server: MyWebServer V1.0\r\n"
        response += "\r\n"
        response += response_body
        return response.encode("utf-8")

    @router('/add')
    def add_stu(self, request):
        name = request['values']['name']
        age = request['values']['age']
        gender = request['values']['gender']
        student_db().add_stu_db(name, age, gender)
        self.__data = self.db.query_stu_db('None')
        return json.dumps(self.__data, ensure_ascii=False)

    @router('/modify')
    def modify_stu(self, request):
        id = request['values']['id']
        name = request['values']['name']
        age = request['values']['age']
        gender = request['values']['gender']
        self.__data = self.db.query_stu_db(id)
        if not self.__data:
            return json.dumps({"msg": f"id为{id}的学生不存在"}, ensure_ascii=False)
        else:
            self.db.modify_stu_db(id, name, age, gender)
            self.__data = self.db.query_stu_db(id)
            return json.dumps(self.__data, ensure_ascii=False)

    @router('/favicon.ico')
    def none(self, request):
        return json.dumps({"msg": "空请求"}, ensure_ascii=False)

    @router('/delete')
    def delete(self, request):
        id = int(request['values']['id'])
        self.__data = self.db.query_stu_db(id)
        if not self.__data:
            return json.dumps({"msg": f"id为{id}的学生不存在"}, ensure_ascii=False)
        else:
            self.db.delete_stu_db(id)
            self.__data = self.db.query_stu_db('None')
            return json.dumps(self.__data, ensure_ascii=False)

    @router('/query')
    def query(self, request):
        id = request['values']['id']
        self.__data = self.db.query_stu_db(id)
        if not self.__data:
            return json.dumps({"msg": f"id为{id}的学生不存在"}, ensure_ascii=False)
        elif not self.__data:
            self.__data = self.db.query_stu_db('None')
            return json.dumps(self.__data, ensure_ascii=False)
        else:
            return json.dumps(self.db.query_stu_db(id), ensure_ascii=False)


if __name__ == '__main__':
    stuweb().startServer()
